
//
// 121226 - AH - Created.
//

package org.japril.swing.jutil.logging;

import java.util.List;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import org.japril.jutil.logging.ControlLogSink;
import org.japril.jutil.logging.ControlLogSink.ClassLogInfo;

/**
 * <p>
 *   {@link TableModel} that adapts the
 *   {@link ClassLogInfo} object to a
 *   {@link ControlLogSink} for a
 *   {@link JTable} view.
 * </p>
 * @author Arne Halvorsen (AH)
 */
@SuppressWarnings("serial")
public final class ControlLogSinkTableModel extends AbstractTableModel
{
  /**
   * <p>
   *   The empty model shared.
   * </p>
   */
  public static final ControlLogSinkTableModel EMPTY_MODEL=
    new ControlLogSinkTableModel();
  
  private final List<ClassLogInfo> m_info;
  
  // Creates the shared empty model.
  private ControlLogSinkTableModel(){ m_info=null; }
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param sink Sink to show info for.
   */
  public ControlLogSinkTableModel(ControlLogSink sink)
  {
    if (sink==null)
    {
      throw new NullPointerException("sink");
    }
    
    m_info=sink.getClassLogInfos();
  }
  
  /**
   * <p>
   *   Gets number of
   *   {@link ClassLogInfo} objects {@code this} has.
   * </p>
   * @return Count.
   */
  public int size(){ return m_info==null ? 0 : m_info.size(); }
  
  /**
   * <p>
   *   Gets
   *   {@link ClassLogInfo}.
   * </p>
   * @param idx Index of element to get.
   * @return Element.
   * @throws IndexOutOfBoundsException If {@code idx<0 || idx>=size()}.
   */
  public ClassLogInfo getClassLogInfo(int idx)
  {
    if (m_info==null)
    {
      throw new IndexOutOfBoundsException(Integer.toString(idx));
    }
    
    return m_info.get(idx);
  }
  
  // Specified in TableModel.
  public int getColumnCount(){ return 3; }

  // Specified in TableModel.
  public int getRowCount(){ return m_info==null ? 0 : m_info.size(); }

  // Specified in TableModel.
  public Object getValueAt(int row, int col)
  {
    if (m_info==null || row<0 || row>=m_info.size())
    {
      throw new IndexOutOfBoundsException("row: "+row);
    }
    
    ClassLogInfo cli=m_info.get(row);
    switch (col)
    {
      case 0 : return cli.getSimpleClassName();
      case 1 : return cli.log();
      case 2 : return cli.getClassName();
      default : throw new IndexOutOfBoundsException("col: "+col);
    }
  }

  // Specified in TableModel.
  public Class<?> getColumnClass(int col)
  {
    switch (col)
    {
      case 0 :
      case 2 : return String.class;
      case 1 : return Boolean.class;
      default : throw new IndexOutOfBoundsException(Integer.toString(col));
    }
  }

  // Specified in TableModel.
  public String getColumnName(int col) 
  {
    switch (col)
    {
      case 0 : return "Class Name";
      case 1 : return "Logs";
      case 2 : return "Qualified Class Name";
      default : throw new IndexOutOfBoundsException(Integer.toString(col));
    }
  }

  // Specified in TableModel.
  public boolean isCellEditable(int row, int col)
  {
    if (m_info==null || row<0 || row>=m_info.size())
    {
      throw new IndexOutOfBoundsException("row: "+row);
    }
    
    switch (col)
    {
      case 0 :
      case 2 : return false;
      case 1 : return true;
      default : throw new IndexOutOfBoundsException(Integer.toString(col));
    }
  }

  // Specified in TableModel.
  public void setValueAt(Object val, int row, int col)
  {
    if (m_info==null || row<0 || row>=m_info.size())
    {
      throw new IndexOutOfBoundsException("row: "+row);
    }
    
    switch (col)
    {
      case 0 :
      case 2 : throw new IllegalArgumentException("col: "+col+" not editable");
      case 1 :
      {
        ClassLogInfo cli=m_info.get(row);
        cli.log((Boolean)val);
        fireTableCellUpdated(row, col);
        return;  
      }
      
      default : throw new IndexOutOfBoundsException(Integer.toString(col));
    }
  }
  
}
